// 1、类型注解
let title1: string;
title1 = '开课吧';
// title1 = 1;  错误

let title2 = 'xx'; // 类型推论
// title2 = 2;

// 数组类型
let names: string[];
names = ['TOM', 'jerry'];

// 任意类型
let foo: any;
foo = 'xx';
foo = 1;

let list:any[];
list = [1, 'abc', true];

// 函数中的类型
// 参数只要指定就要传递
// 可选参数 ？
function greeting(preson: string, age?: number): string {
    return 'hello, ' + preson;
}
const abc = greeting('tom');

// void类型
function warnUser(): void {}

interface Person {
    firstName: string;
    lastName: string;
}
function greeting2(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}
const user = {firstName: "Jane", lastName: 'User'};
console.log(greeting2(user));

// 不用泛型
// interface Result1 {
//     data: Feature[];
// }

// 类装饰器表达式会在运行时当作函数被调用，类的构造函数作为其唯一的参数
function log(target: Function) {
    // target是构造函数
    console.log(target === Foo); // true
    target.prototype.log = function() {
        console.log(this.bar);
    }
    // 如果类装饰器返回一个值，它会使用提供的构造函数来替换类的声明
}

@log
class Foo {
    bar = 'bar'
}

const foo2 = new Foo();
// @ts-ignore
foo2.log()